package cn.edu.nju.ws.sview.servlets;

import java.io.IOException;
import java.net.URLDecoder;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;

import cn.edu.nju.ws.sview.cache.DomainCache;
import cn.edu.nju.ws.sview.cache.GroupNameIDCache;
import cn.edu.nju.ws.sview.cache.RangeCache;
import cn.edu.nju.ws.sview.cache.URIIDCache;
import cn.edu.nju.ws.sview.cache.URILabelCache;
import cn.edu.nju.ws.sview.cache.URITypeCache;
import cn.edu.nju.ws.sview.cache.UserNameIDCache;
import cn.edu.nju.ws.sview.cache.ViewCache;
import cn.edu.nju.ws.sview.crawler.Crawler;
import cn.edu.nju.ws.sview.crawler.Element;
import cn.edu.nju.ws.sview.database.DBConnectionFactory;
import cn.edu.nju.ws.sview.database.DBOperations;
import cn.edu.nju.ws.sview.rdf.ResourceFactory;
import cn.edu.nju.ws.sview.rdf.URIResource;
import cn.edu.nju.ws.sview.reasoning.Atom;
import cn.edu.nju.ws.sview.reasoning.Predicate;
import cn.edu.nju.ws.sview.reasoning.Rule;
import cn.edu.nju.ws.sview.reasoning.Term;
import cn.edu.nju.ws.sview.reasoning.Variable;
import cn.edu.nju.ws.sview.util.URIUtil;
import cn.edu.nju.ws.sview.views.Collaboration;
import cn.edu.nju.ws.sview.views.CustomDataMember;
import cn.edu.nju.ws.sview.views.CustomDataMember.Base;
import cn.edu.nju.ws.sview.views.DataMember;
import cn.edu.nju.ws.sview.views.URIDataMember;
import cn.edu.nju.ws.sview.views.View;
import cn.edu.nju.ws.sview.views.data.ViewEditing;
import cn.edu.nju.ws.sview.views.data.ViewEditing.DataMemberItem;


/**
 * Servlet implementation class ViewEditServlet
 */
@WebServlet("/ViewEditServlet")
public class ViewEditServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	public static final String STATUS_CONFLICT = "conflict";
	public static final String STATUS_NEW_CHILD = "newchild";
	public static final String STATUS_UPDATE = "update";
	public static final String STATUS_REMOVE = "removed";
	public static final String STATUS_NOAUTHORITY = "noauthority";
	public static final String STATUS_OK = "ok";
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ViewEditServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub\
		String option=null;
		String json=null;
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		if(request.getParameter("dmsearch")!=null){
			json = request.getParameter("dmsearch");
			option="dmsearch";
		}
		else if(request.getParameter("forward")!=null){
			json = request.getParameter("forward");
			option="forward";
		}
		else if(request.getParameter("backward")!=null){
			json = request.getParameter("backward");
			option="backward";
		}
		else if(request.getParameter("mygroup")!=null){
			json = request.getParameter("mygroup");
			option="mygroup";
		}
		else if(request.getParameter("othergroups")!=null){
			json = request.getParameter("othergroups");
			option="othergroups";
		}
		else if(request.getParameter("dmnameCheck")!=null){
			json = request.getParameter("dmnameCheck");
			option="dmnameCheck";
		}
	    else if(request.getParameter("availableChainLink")!=null){
			json = request.getParameter("availableChainLink");
			option="availableChainLink";
		}
		else if(request.getParameter("createTmpChain")!=null){
			json = request.getParameter("createTmpChain");
			option="createTmpChain";
		}
		else if(request.getParameter("deldm")!=null){
			json = request.getParameter("deldm");
			option="deldm";
		}	
		else if(request.getParameter("delrule")!=null){
			json = request.getParameter("delrule");
			option="delrule";
		}	
		else if(request.getParameter("storedm")!=null){
			json = request.getParameter("storedm");
			option="storedm";
		}
		else if(request.getParameter("storelayout")!=null){
			json = request.getParameter("storelayout");
			option="storelayout";
		}
		else if(request.getParameter("storeviewinfo")!=null){
			json = request.getParameter("storeviewinfo");
			option="storeviewinfo";
		}
		else if(request.getParameter("viewDMInit")!=null){
			json = request.getParameter("viewDMInit");
			option="viewDMInit";
		}
		else if(request.getParameter("ruleinfo")!=null){
			json = request.getParameter("ruleinfo");
			option="ruleinfo";
		}
		
		if(option.equals("dmsearch")){
			String str = URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			String kw = (String)regtJSON.get("kw") ;
			String lang = (String)regtJSON.get("lang") ;
			String user = (String)regtJSON.get("user") ;
			int etype = ((Long)(regtJSON.get("etype"))).intValue();
			int eid = ((Long)(regtJSON.get("eid"))).intValue();
			int groupID = Integer.valueOf((String)(regtJSON.get("groupID")));
			boolean isInner= Integer.parseInt((String)(regtJSON.get("isInner")))==1?true:false;
			int cid = Integer.parseInt((String)(regtJSON.get("cid")));
				
			ArrayList<DataMemberItem> array = null;
			array  = ViewEditing.kw2Datamember(groupID,kw, lang,etype,eid,isInner,cid) ;
			JSONArray elements = new JSONArray();
			for(DataMemberItem item:array){
				JSONObject jsob = new JSONObject();
				
				int dmtype = item.getDMType();
				int dmid = item.getDMID();
				String name = item.getName();
				int inverse = item.getInverse()?1:0;
				int arity = item.getArity();
				int functional = item.getFunctional()?1:0;
				int hasAuthor = item.hasAuthor()?1:0;
				String category = item.getCategory();
				jsob.put("dmtype", dmtype) ;
				jsob.put("dmid", dmid) ;
				jsob.put("name", name);
				jsob.put("inverse", inverse);
				jsob.put("arity", arity) ;
				jsob.put("vtype",item.getValueType() );
				jsob.put("functional", functional);
				jsob.put("hasAuthor", hasAuthor);
				jsob.put("category", category);
		        elements.add(jsob) ;
			}
		    response.getWriter().print(elements) ;
 		}
		else if(option.equals("forward")||option.equals("backward")){
			String str =  URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			String lang = (String) regtJSON.get("lang");
			int etype = ((Long) (regtJSON.get("etype"))).intValue();
			int eid = ((Long) (regtJSON.get("eid"))).intValue();

			ArrayList<DataMemberItem> array = null;
			if (option.equals("forward"))
				array = ViewEditing.getForwardDM(lang, etype, eid,true);
			else
				array = ViewEditing.getBackwardDM(lang, etype, eid,true);
			JSONArray elements = new JSONArray();
			for (DataMemberItem item : array) {
				JSONObject jsob = new JSONObject();

				int dmtype = item.getDMType();
				int dmid = item.getDMID();
				String name = item.getName();
				int inverse = item.getInverse() ? 1 : 0;
				int arity = item.getArity();
				int functional = item.getFunctional() ? 1 : 0;
				int hasAuthor = item.hasAuthor() ? 1 : 0;
				jsob.put("dmtype", dmtype);
				jsob.put("dmid", dmid);
				jsob.put("name", name);
				jsob.put("inverse", inverse);
				jsob.put("arity", arity);
				jsob.put("vtype", item.getValueType());
				jsob.put("functional", functional);
				jsob.put("hasAuthor", hasAuthor);
				elements.add(jsob);
			}
			response.getWriter().print(elements);
 		}
		else if(option.equals("mygroup")||option.equals("othergroups")){
			String str = URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			String lang = (String)regtJSON.get("lang") ;
			int groupID = Integer.parseInt((String)(regtJSON.get("gid")));
			int etype = ((Long)(regtJSON.get("etype"))).intValue();
			int eid = ((Long)(regtJSON.get("eid"))).intValue();
			boolean isInner= Integer.parseInt((String)(regtJSON.get("isInner")))==1?true:false;
			int cid = Integer.parseInt((String)(regtJSON.get("cid")));

			ArrayList<DataMemberItem> array = null;
			if (option.equals("mygroup"))
				array = ViewEditing.getMyGroupDM(groupID,isInner, cid,true) ;
			else
				array = ViewEditing.getOtherGroupDM(groupID, isInner, cid,true) ;
			
			System.out.println(array.size()+"|"+array.toString());
			JSONArray elements = new JSONArray();
			for (DataMemberItem item : array) {
				JSONObject jsob = new JSONObject();

				int dmtype = item.getDMType();
				int dmid = item.getDMID();
				String name = item.getName();
				int inverse = item.getInverse() ? 1 : 0;
				int arity = item.getArity();
				int functional = item.getFunctional() ? 1 : 0;
				int hasAuthor = item.hasAuthor() ? 1 : 0;
				jsob.put("dmtype", dmtype);
				jsob.put("dmid", dmid);
				jsob.put("name", name);
				jsob.put("inverse", inverse);
				jsob.put("arity", arity);
				jsob.put("vtype", item.getValueType());
				jsob.put("functional", functional);
				jsob.put("hasAuthor", hasAuthor);
				elements.add(jsob);
			}
			response.getWriter().print(elements);
 		}
		
		else if(option.equals("createTmpChain")){
			String str =  URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			String name = (String)regtJSON.get("name") ;
			int groupID = Integer.parseInt((String)regtJSON.get("groupID")) ;
			int classID = Integer.parseInt((String)regtJSON.get("classID")) ;
			boolean isInner = Integer.parseInt((String)regtJSON.get("isInner"))==1?true:false;
			int vtype = Integer.parseInt(((String)regtJSON.get("vtype"))) ;
			int make_method =((Long)regtJSON.get("makeMethod")).intValue() ;
			
			JSONArray json_array = (JSONArray)regtJSON.get("base") ;
			ArrayList<Base> bases =new ArrayList<Base>();
			for(int i=0;i<json_array.size();i++){
				JSONObject jsob = (JSONObject)json_array.get(i) ;
				int type = Integer.parseInt((String)jsob.get("type"));
				int id = Integer.parseInt((String)jsob.get("id"));
				int inverseInt = Integer.parseInt((String)jsob.get("inverse"));
			    boolean inverse = inverseInt==1?true:false;
			    if(type==DataMember.URI_DATAMEMBER){
			    	Base base = new Base(type,id,inverse);
			    	bases.add(base) ;
			    }else{
					boolean isChain = false;
					// 判断是否base也是chain生成的
					if (CustomDataMember.getMakeMethodByDMId(id) == DataMember.MAKE_METHOD_CHAIN) {
						isChain = true;
					}
					if (!isChain) {
						Base base = new Base(type,id,inverse);
						bases.add(base);
					} else {
						ArrayList<Base> chainbases = CustomDataMember
								.getBasesByDMId(id);
						bases.addAll(chainbases);
					}
			    }
			}
			
			String group=null;
			try {
				group = GroupNameIDCache.getInstance().getName(groupID);
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			int start = CustomDataMember.getLatestCopyVersion(name,
					group,isInner,classID,true);
			boolean flag =true;
			String mname = null;
			while(flag){
				//String name, String group, int valueType,
				//int makeMethod, boolean isInner, int classID,boolean isCopy
				start++;
				mname= name+"("+start+")";
				int dmId = CustomDataMember.getDMIdByNameGroupClassIDIsCopy(mname, groupID,isInner,classID,true);
				if(dmId>=0)
					flag = true;
				else
					flag = false;
			}
			CustomDataMember cdm = new CustomDataMember(mname,group,vtype,make_method,bases,isInner,classID,true);
            cdm.serialize();
            int dmid = cdm.getID();
            CustomDataMember.setTMP(dmid, true);
			int dmtype = DataMember.CUSTOM_DATAMEMBER;
			int inv = 0;
			JSONObject result = new JSONObject();
	        result.put("name", mname);
			result.put("dmtype", dmtype) ;
			result.put("dmid", dmid) ;
			result.put("inverse", inv) ;
			response.getWriter().print(result) ;
 		}
		else if(option.equals("deldm")){
			String str =  URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			int classID = Integer.parseInt((String)regtJSON.get("classID")) ;
			boolean isInner = Integer.parseInt((String)regtJSON.get("isInner"))==1?true:false;
			int dmtype = Integer.parseInt(((String)regtJSON.get("dmtype"))) ;
			int dmid =Integer.parseInt(((String)regtJSON.get("dmid"))) ;
			String userName =(String)regtJSON.get("userName");
			int userID = -1;
			try {
				userID = UserNameIDCache.getInstance().getUserID(userName);
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			boolean getAuthority = Collaboration.getInstance()
			.getEditAuthority(Collaboration.DM, dmid, userID);
			if(getAuthority){
				boolean inner = CustomDataMember.isInner(dmid);
				int cid = CustomDataMember.getClassIDByDMID(dmid);
				if (inner == isInner && cid == classID) {
					CustomDataMember.delete(dmid);
				}
				response.getWriter().print("ok");
				Collaboration.getInstance().recoverAuthority(Collaboration.DM, dmid) ;
			}else{
				response.getWriter().print("noauthority");
			}
		}
		else if(option.equals("delrule")){
			String str =  URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			int classID = Integer.parseInt((String)regtJSON.get("classID")) ;
			boolean isInner = Integer.parseInt((String)regtJSON.get("isInner"))==1?true:false;
			int dmtype = Integer.parseInt(((String)regtJSON.get("dmtype"))) ;
			int dmid =Integer.parseInt(((String)regtJSON.get("dmid"))) ;
			JSONArray rowIDs =(JSONArray)regtJSON.get("rowIDs") ;
			String userName =(String)regtJSON.get("userName");
			int userID = -1;
			try {
				userID = UserNameIDCache.getInstance().getUserID(userName);
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			boolean getAuthority = Collaboration.getInstance()
			.getEditAuthority(Collaboration.DM, dmid, userID);
			if(getAuthority){
				for(int i=0;i<rowIDs.size();i++){
					int rowID = Integer.valueOf((String)rowIDs.get(i));
					CustomDataMember.deleteRuleByRowID(rowID);
				}
			
				response.getWriter().print("ok");
				Collaboration.getInstance().recoverAuthority(Collaboration.DM, dmid) ;
			}else{
				response.getWriter().print("noauthority");
			}
		}
		else if(option.equals("dmnameCheck")){
			String str =  URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			String name = (String)regtJSON.get("name") ;
			int  groupID = Integer.parseInt((String)regtJSON.get("groupID")) ;
			boolean isInner =Integer.parseInt((String)regtJSON.get("isInner"))==1?true:false;
			int classID = Integer.parseInt((String)regtJSON.get("classID"));
			int dmtype = Integer.parseInt((String)regtJSON.get("dmtype"));
			int dmid = Integer.parseInt((String)regtJSON.get("dmid"));
			String userName =(String)regtJSON.get("userName");
			int userID = -1;
			try {
				userID = UserNameIDCache.getInstance().getUserID(userName);
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			boolean getAuthority = Collaboration.getInstance()
					.getEditAuthority(Collaboration.DM, dmid, userID);

			if (getAuthority) {
				String status = ViewEditServlet.STATUS_CONFLICT;
				if (dmid > 0) {
					if (CustomDataMember.getCustomDataMemberById(dmid) == null) {
						status = ViewEditServlet.STATUS_REMOVE;
					} else {

						boolean inner = CustomDataMember.isInner(dmid);
						int cid = CustomDataMember.getClassIDByDMID(dmid);
						if (inner == isInner && classID == cid) {
							int cdmid = CustomDataMember
									.getDMIdByNameGroupClassIDIsCopy(name,
											groupID, isInner, classID, false);
							if (cdmid <= 0) {
								status = ViewEditServlet.STATUS_UPDATE;
							} else if (cdmid != dmid) {
								status = ViewEditServlet.STATUS_CONFLICT;
							} else {
								status = ViewEditServlet.STATUS_UPDATE;
							}

						} else {
							int cdmid = CustomDataMember
									.getDMIdByNameGroupClassIDIsCopy(name,
											groupID, isInner, classID, false);
							if (cdmid > 0)
								status = ViewEditServlet.STATUS_CONFLICT;
							else
								status = ViewEditServlet.STATUS_NEW_CHILD;
						}
					}
				} else {
					int cdmid = CustomDataMember
							.getDMIdByNameGroupClassIDIsCopy(name, groupID,
									isInner, classID, false);
					if (cdmid > 0)
						status = ViewEditServlet.STATUS_CONFLICT;
					else
						status = ViewEditServlet.STATUS_NEW_CHILD;
				}
                
				if(status.equals(STATUS_CONFLICT)||status.equals(STATUS_REMOVE)){
					Collaboration.getInstance().recoverAuthority(Collaboration.DM, dmid);
				}
				response.getWriter().print(status);
			} else {
				response.getWriter().print("noauthority");
			}
 		}
        else if(option.equals("availableChainLink")){
			String str = URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			JSONArray json_array = (JSONArray)regtJSON.get("entity") ;
			String lang = (String)regtJSON.get("lang") ;
			
			ArrayList<URIResource> array = new ArrayList<URIResource>();
			HashSet<Integer> uriIDs =new HashSet<Integer>();
		    for(int i=0;i<json_array.size();i++){
		    	int mid = Integer.parseInt(((String)json_array.get(i))) ;
		    	uriIDs.add(new Integer(mid)) ;
		    	try{
		    		URIResource r = ResourceFactory.getInstance().createURIResource(URIIDCache.getInstance().getURI(mid));
		    		if(DBOperations.getValidStatus(mid)!=URIResource.VALID&&
							Crawler.getInstance().checkStatus(r)==Crawler.STATUS_UNSUBMITTED){
		    			Crawler.getInstance().submitURI(r);
		    			Crawler.getInstance().promoteWeight(r, Element.LEVEL_1);
		    			array.add(r);
		    		}
		    	}catch(Throwable e){
		    		e.printStackTrace();
		    	}
		    }
		    boolean waitflag = true;
		    while(waitflag){
		    	waitflag =false;
		    	 for(URIResource resource:array){
		    	     int status = Crawler.getInstance().checkStatus(resource) ;
		    	     if(status!=Crawler.STATUS_DONE){
		    	    	 waitflag = true;
		    	    	 break;
		    	     }
		    	 }
		    	 try {
					Thread.sleep(20);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		    }
		    
		    HashSet<Integer> ranges =new HashSet<Integer>();
 /*get forward datamembers*/
			HashSet<DataMember> dms = View.getFowardMembers(uriIDs);
			JSONArray result = new JSONArray();
			array.clear();
			for(DataMember dm:dms){
				URIDataMember udm = (URIDataMember)dm;
				String uri = udm.getURI();
				try {
					int uriID = URIIDCache.getInstance().getURIID(uri, true);
					ranges.addAll(RangeCache.getInstance().getRange(uriID));
					String label = URILabelCache.getInstance().getLabel(uriID, lang) ;
					if(label.equals("")){
						URIResource uri_resource = ResourceFactory.getInstance().createURIResource(uri);
						String status = DBOperations.getValidStatus(uriID);
						if(!status.equals(URIResource.VALID)&&
							Crawler.getInstance().checkStatus(uri_resource)==Crawler.STATUS_UNSUBMITTED){
							Crawler.getInstance().submitURI(uri_resource) ; 
							Crawler.getInstance().promoteWeight(uri_resource, Element.LEVEL_1);
							array.add(uri_resource) ;
						}else{
							label = URIUtil.getLocalname(uri);
							int dmtype = DataMember.URI_DATAMEMBER;
							JSONObject object = new JSONObject();
							object.put("dmtype", dmtype) ;
							object.put("dmid", uriID) ;
							object.put("name", label) ;
							object.put("inverse", 0);
						    int vtype = URIDataMember.getValueTypeByDMId(uriID, false);
						    object.put("vtype", vtype);
						    result.add(object) ;
						}
					}else{
						int dmtype = DataMember.URI_DATAMEMBER;
						JSONObject object = new JSONObject();
						object.put("dmtype", dmtype) ;
						object.put("dmid", uriID) ;
						object.put("name", label) ;
						object.put("inverse", 0);
					    int vtype = URIDataMember.getValueTypeByDMId(uriID, false);
					    object.put("vtype", vtype);
					    result.add(object) ;
					}
				} catch (Throwable e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			waitflag = true;
			  while(waitflag){
			    	waitflag =false;
			    	 for(URIResource resource:array){
			    	     int status = Crawler.getInstance().checkStatus(resource) ;
			    	     if(status!=Crawler.STATUS_DONE){
			    	    	 waitflag = true;
			    	    	 break;
			    	     }
			    	 }
			    	 try {
						Thread.sleep(20);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
			  }
			  for(URIResource resource:array){
				try {
					int uriID = URIIDCache.getInstance().getURIID(
							resource.getURI(), true);
					String label = URILabelCache.getInstance().updateLabel(
							uriID, lang);
					if (label.equals("")) {
						label = URIUtil.getLocalname(URIIDCache.getInstance()
								.getURI(uriID));
					}
					int dmtype = DataMember.URI_DATAMEMBER;
					JSONObject object = new JSONObject();
					object.put("dmtype", dmtype);
					object.put("dmid", uriID);
					object.put("name", label);
					object.put("inverse", 0);
					int vtype = URIDataMember.getValueTypeByDMId(uriID, false);
					object.put("vtype", vtype);
					result.add(object);
				} catch (Throwable e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			  }
/*end: get forward datamembers*/
			  
/*start:get backward datamembers*/
				HashSet<DataMember> backdms = View.getBackwardMembers(uriIDs);
				array.clear();
				for(DataMember dm:backdms){
					URIDataMember udm = (URIDataMember)dm;
					String uri = udm.getURI();
					try {
						int uriID = URIIDCache.getInstance().getURIID(uri, true);
						ranges.addAll(DomainCache.getInstance().getDomain(uriID));
						String label = URILabelCache.getInstance().getLabel(uriID, lang) ;
						if(label.equals("")){
							URIResource uri_resource = ResourceFactory.getInstance().createURIResource(uri);
							String status = DBOperations.getValidStatus(uriID);
							if(!status.equals(URIResource.VALID)&&
								Crawler.getInstance().checkStatus(uri_resource)==Crawler.STATUS_UNSUBMITTED){
								Crawler.getInstance().submitURI(uri_resource) ; 
								Crawler.getInstance().promoteWeight(uri_resource, Element.LEVEL_1);
								array.add(uri_resource) ;
							}else{
								label = URIUtil.getLocalname(uri);
								int dmtype = DataMember.URI_DATAMEMBER;
								JSONObject object = new JSONObject();
								object.put("dmtype", dmtype) ;
								object.put("dmid", uriID) ;
								object.put("name", label) ;
								object.put("inverse", 1);
							    int vtype = URIDataMember.getValueTypeByDMId(uriID, true);
							    object.put("vtype", vtype);
							    result.add(object) ;
							}
						}else{
							int dmtype = DataMember.URI_DATAMEMBER;
							JSONObject object = new JSONObject();
							object.put("dmtype", dmtype) ;
							object.put("dmid", uriID) ;
							object.put("name", label) ;
							object.put("inverse", 1);
						    int vtype = URIDataMember.getValueTypeByDMId(uriID, true);
						    object.put("vtype", vtype);
						    result.add(object) ;
						}
					} catch (Throwable e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				waitflag = true;
				  while(waitflag){
				    	waitflag =false;
				    	 for(URIResource resource:array){
				    	     int status = Crawler.getInstance().checkStatus(resource) ;
				    	     if(status!=Crawler.STATUS_DONE){
				    	    	 waitflag = true;
				    	    	 break;
				    	     }
				    	 }
				    	 try {
							Thread.sleep(20);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
				  }
				  for(URIResource resource:array){
					try {
						int uriID = URIIDCache.getInstance().getURIID(
								resource.getURI(), true);
						String label = URILabelCache.getInstance().updateLabel(
								uriID, lang);
						if (label.equals("")) {
							label = URIUtil.getLocalname(URIIDCache.getInstance()
									.getURI(uriID));
						}
						int dmtype = DataMember.URI_DATAMEMBER;
						JSONObject object = new JSONObject();
						object.put("dmtype", dmtype);
						object.put("dmid", uriID);
						object.put("name", label);
						object.put("inverse", 1);
						int vtype = URIDataMember.getValueTypeByDMId(uriID, true);
						object.put("vtype", vtype);
						result.add(object);
					} catch (Throwable e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				  }
/*end:get backward datamembers*/
			  
/*get custom datambers*/
			  //first get types of uris
			  HashSet<Integer> types = new HashSet<Integer>();
			  for(Integer uid:uriIDs){
				  try {
					types.addAll(URITypeCache.getInstance().getTypes(uid));
				} catch (Throwable e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			  }
			  //add range properties into uris
			  types.addAll(ranges) ;
			  
			  //then get the custom datamembers whose types are superclass of types
			  HashSet<DataMemberItem> customArray = new HashSet<DataMemberItem>();
			  for(Integer typeID:types){
				  customArray.addAll(ViewEditing.getCustomDM(lang, false, typeID,true));
			  }
			  for(DataMemberItem item:customArray){
				  int dmtype = DataMember.CUSTOM_DATAMEMBER;
				  JSONObject object = new JSONObject();
				  object.put("dmtype", dmtype);
				  object.put("dmid", item.getDMID());
				  object.put("name", item.getName());
				  object.put("inverse", 0);
				  object.put("vtype", item.getValueType());
				  result.add(object);
			  }
/*end: get custom datamembers*/
			  
			  response.getWriter().print(result) ;
 		}
 		else if(option.equals("storedm")){
 			JSONObject result = new JSONObject();
 			/**
 			 * 返回值类型：jsonobject，
 			 * 其包含status:ok,noautority,conflict,removed
 			 * 并且status=ok时返回
 			 * 新建或更新dmtype,dmid,name,inverse,arity,vtype,functional,hasauthor以及
 			 * 是新建还是更新的详细状态
 			 */
			String str = URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			String name = (String)regtJSON.get("name") ;
			int  groupID = Integer.parseInt((String)regtJSON.get("groupID")) ;
			boolean isInner =Integer.parseInt((String)regtJSON.get("isInner"))==1?true:false;
			int classID = Integer.parseInt((String)regtJSON.get("classID"));
			int dmtype = Integer.parseInt((String)regtJSON.get("dmtype"));
			int dmid = Integer.parseInt((String)regtJSON.get("dmid"));
			int vtype =  Integer.parseInt((String)regtJSON.get("vtype"));
			JSONArray dmjson = (JSONArray)regtJSON.get("bases");
			String userName =(String)regtJSON.get("userName");
			
			int userID = -1;
			try {
				userID = UserNameIDCache.getInstance().getUserID(userName);
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			String group =null;
			try {
				group = GroupNameIDCache.getInstance().getName(groupID);
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			ArrayList<Base> bases = new ArrayList<Base>();
			ArrayList<Base> tmp = new ArrayList<Base>();
			for(int i=0;i<dmjson.size();i++){
				JSONObject itemob = (JSONObject)dmjson.get(i);
				int basedmtype =Integer.parseInt((String)(itemob.get("dmtype")));
				int basedmid =Integer.parseInt((String)(itemob.get("dmid")));
				//check whether the datamember exist
			    if(basedmtype==DataMember.URI_DATAMEMBER){
			    	try {
						if(URIIDCache.getInstance().getURI(basedmid)==null){
							continue;
						}
					} catch (Throwable e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
			    }else{
			    	if(CustomDataMember.getCustomDataMemberById(basedmid)==null){
			    		continue;
			    	}
			    }
				boolean inverse = Integer.parseInt((String)(itemob.get("inverse")))==1?true:false;
				boolean origin = (Boolean)(itemob.get("origin"));
			    Base base = new Base(basedmtype,basedmid,inverse);
			    bases.add(base);
			    if(!origin){
			    	tmp.add(base);
			    }
			}
			
			boolean getAuthority = Collaboration.getInstance()
					.getEditAuthority(Collaboration.DM, dmid, userID);

			if (getAuthority) {
				// 同步锁
				Object groupLock = Collaboration.getInstance()
						.getGroupProductLock(Collaboration.DM, groupID);
				
				// 判断以dmid标识的data member是否因协同编辑而在别处已被删除
				boolean isthere = true;
				if (dmid > 0) {
					synchronized (groupLock) {
						isthere = CustomDataMember.isThere(dmid);
					}
				}
				if (!isthere) {
					Collaboration.getInstance().recoverAuthority(Collaboration.DM, dmid);
					result.put("status", this.STATUS_REMOVE);
				} else{
					
					CustomDataMember cdmrs = null;
					boolean exist = false;
					int detail_status = -1; //0表示新建，1 表示更新
					//同步代码块
					synchronized (groupLock) {
						if (dmid > 0) {
								boolean inner = CustomDataMember.isInner(dmid);
								int cid = CustomDataMember.getClassIDByDMID(dmid);
								if (inner == isInner && classID == cid) {
									int cdmid = CustomDataMember
											.getDMIdByNameGroupClassIDIsCopy(name,
													groupID, isInner, classID, false);
									if(cdmid>0&&cdmid!=dmid){
										exist = true;
									}else{
										detail_status = 1;
									}
								} else {
									int cdmid = CustomDataMember
											.getDMIdByNameGroupClassIDIsCopy(name,
													groupID, isInner, classID, false);
									if (cdmid > 0)
										exist = true;
									else{
										detail_status=0;
									}
								}
								
								//在dmid>0情况下，名字不冲突，赶紧存储
								//其它datamember就不能使用相同名字了
								if (!exist) {
									if (inner == isInner && classID == cid) {
										// it means rename the datamember
										CustomDataMember.rename(dmid, name, groupID, isInner, classID, false);
									    CustomDataMember.appendMemberOfDM(dmid, bases);
									    cdmrs = CustomDataMember.getCustomDataMemberById(dmid);
									} else {
										// it means creats a new datamember on minimal
										// class
										cdmrs = new CustomDataMember(name,group, vtype,DataMember.MAKE_METHOD_MERGE,bases,isInner,classID,false);
										cdmrs.serialize();
									}
								}
						} else {
							int cdmid = CustomDataMember
									.getDMIdByNameGroupClassIDIsCopy(name, groupID,
											isInner, classID, false);
							if (cdmid > 0)
							    exist = true;
							else{
								detail_status = 0;
							}
							
							if(!exist){
								//在dmid<=0情况下，名字不冲突，赶紧存储
								//哦也，由于在同步代码块内，其它view就不能使用相同名字了
								cdmrs = new CustomDataMember(name,group, vtype,DataMember.MAKE_METHOD_MERGE,bases,isInner,classID,false);
								cdmrs.serialize();
							}
						}
					}
					
					//非同步代码块
					if(!exist){
						
						//软件制品解锁
						Collaboration.getInstance().recoverAuthority(Collaboration.DM, dmid);
						
						result.put("status", this.STATUS_OK);
						result.put("dmtype", DataMember.CUSTOM_DATAMEMBER);
						result.put("dmid", cdmrs.getID());
						result.put("name", name);
						result.put("inverse", 0);
						result.put("arity", cdmrs.getArity());
						result.put("vtype", cdmrs.getValueType());
						result.put("functional", cdmrs.getFunctional());
						result.put("hasAuthor", true);
						if(detail_status==0){
							result.put("detail_status", this.STATUS_NEW_CHILD);
						}else if(detail_status==1){
							result.put("detail_status", this.STATUS_UPDATE);
						}
					}else{
						Collaboration.getInstance().recoverAuthority(
								Collaboration.DM, dmid);
						result.put("status", this.STATUS_CONFLICT);
					}
				}
			} else {
				//没有编辑权限，返回noauthority
				result.put("status", this.STATUS_NOAUTHORITY);
			}
			
			//最终返回结果
			response.getWriter().print(result);
 		}
 		else if(option.equals("storeviewinfo")){
 			JSONObject result = new JSONObject();
 			/**
 			 * 返回值类型：jsonobject，
 			 * 其包含status:ok,noautority,conflict,removed
 			 * 并且status=ok时返回新建或更新view的id
 			 */
			String str = URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			String name = (String)regtJSON.get("name") ;
			String user = (String)regtJSON.get("user") ;
			int  groupID = Integer.parseInt((String)regtJSON.get("groupID")) ;
			boolean isInner =Integer.parseInt((String)regtJSON.get("isInner"))==1?true:false;
			int classID = Integer.parseInt((String)regtJSON.get("classID"));
			String lang = (String)regtJSON.get("lang") ;
			int viewID = Integer.parseInt(((String)regtJSON.get("viewID")));
			
			String group = null;
			try {
				group = GroupNameIDCache.getInstance().getName(groupID);
			} catch (Throwable e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
			int userID = -1;
			try {
				userID = UserNameIDCache.getInstance().getUserID(user);
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			boolean getAuthority = Collaboration.getInstance()
					.getEditAuthority(Collaboration.VIEW, viewID, userID);
			if (getAuthority) {
				// 同步锁
				Object groupLock = Collaboration.getInstance()
						.getGroupProductLock(Collaboration.VIEW, groupID);

				// 判断以viewID标识的View是否因协同编辑而在别处已被删除
				boolean isthere = true;
				if (viewID > 0) {
					synchronized (groupLock) {
						isthere = View.isThere(viewID);
					}
				}
				if (!isthere) {
					Collaboration.getInstance().recoverAuthority(Collaboration.VIEW, viewID);
					result.put("status", this.STATUS_REMOVE);
				} else {

					int initialViewID = viewID;
					boolean exist = false;
					/*
					 * viewID>0 means the user is editing a view If the view's
					 * class equals editing class, need check whether <groupID
					 * ,name, isInner,classID> exists exclude viewID Else
					 * whether <groupID ,name, isInner,classID> exist
					 */
					synchronized(groupLock){
						if (viewID > 0) {
							boolean inner = View.isInner(viewID);
							int cid = View.getClassIDByViewID(viewID);
							if (inner == isInner && classID == cid) {
								int vid = View.getViewIdByNameGroupClassID(
										name, groupID, isInner, classID);
								if (vid > 0 & vid != viewID)
									exist = true;
							} else {
								int vid = View.getViewIdByNameGroupClassID(
										name, groupID, isInner, classID);
								if (vid > 0)
									exist = true;
							}
							
							//在viewID>0情况下，名字不冲突，赶紧存储
							//哦也，由于在同步代码块内，其它view就不能使用相同名字了
							if (!exist) {
								if (inner == isInner && classID == cid) {
									// it means rename the view
									View view = View.getViewByViewId(viewID);
									view.rename(name);
								} else {
									// it means creats a new view on minimal
									// class
									String classURIStr = View.genClassURIStr(
											isInner, classID);
									View view = new View(name, group, isInner,
											classURIStr, lang);
									view.serializeByEdit();
									viewID = view.getID();
								}
							}
						} else {
							int vid = View.getViewIdByNameGroupClassID(name,
									groupID, isInner, classID);
							if (vid > 0)
								exist = true;
							
							//在viewID<=0情况下，名字不冲突，赶紧存储
							//哦也，由于在同步代码块内，其它view就不能使用相同名字了
							if (!exist) {
								//it means create a new view
						    	String classURIStr = View.genClassURIStr(isInner, classID) ;
								View view = new View(name,group,isInner,classURIStr,lang) ;
								view.serializeByEdit() ;
								viewID =view.getID();
							}
						}
					}

					if (!exist) {
						//非同步代码块
						/*add to favor views*/
						View.addFavorViewsForClassLangUser(viewID, user, classID, lang,isInner);
						
						/*store view datamembers*/
						ArrayList<DataMember> datamembers = new ArrayList<DataMember>();
						JSONArray dms = (JSONArray)regtJSON.get("dms");
						ArrayList<String> labels =new ArrayList<String>();
						for(int i=0;i<dms.size();i++){
							JSONObject myob = (JSONObject)dms.get(i) ;
							int dmtype = Integer.parseInt((String)myob.get("dmtype"));
							int dmid = Integer.parseInt((String)myob.get("dmid"));
							int inverseInt = Integer.parseInt((String)myob.get("inverse"));
							boolean inverse = inverseInt==1?true:false;
							int funcInt = ((Long)myob.get("func")).intValue();
							boolean functional = funcInt ==1?true:false;
							int value_type =  Integer.parseInt((String)myob.get("vtype"));
							String label = (String)myob.get("label") ;
							labels.add(label) ;
							if(dmtype==DataMember.CUSTOM_DATAMEMBER){
								CustomDataMember cdm = CustomDataMember.getCustomDataMemberById(dmid) ;
								if(cdm==null)
									continue;
								cdm.setFunctional(functional);
								cdm.setValueType(value_type);
								datamembers.add(cdm) ;
							}else{
								URIDataMember udm = null;
								String dmuri = null;
								try {
									dmuri = URIIDCache.getInstance().getURI(dmid);
								} catch (Throwable e1) {
									// TODO Auto-generated catch block
									e1.printStackTrace();
								}
								if(dmuri==null)
									continue;
								try {
									udm = new URIDataMember(dmuri);
								} catch (Throwable e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
								udm.setInverse(inverse) ;
								udm.setValueType(value_type);
								udm.setFunctional(functional) ;
								datamembers.add(udm) ;
							}
						}
						
						View.serializeDataMembers(viewID, groupID, datamembers, labels);
						
						/* store layout */
						try {
							int layout = Integer.parseInt((String) regtJSON
									.get("layout"));
							Connection con = DBConnectionFactory
									.getConnection();
							PreparedStatement ps = con
									.prepareStatement("insert into user_view(user_id,view_id,layout) values(?,?,?)"
											+ " on duplicate key update layout =values(layout)");
							ps.setInt(1, UserNameIDCache.getInstance()
									.getUserID(user));
							ps.setInt(2, viewID);
							ps.setInt(3, layout);
							ps.executeUpdate();
							ps.close();
							con.close();
						} catch (Throwable e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}

						/* update class-view cache */
						ViewCache.getInstance().addViewIntoCache(isInner, classID,
								viewID, lang);
		                
						/*store view reference*/
						HashSet<Integer> cdms = View.getReferedCustomDataMemberIDs(viewID);
						
						HashMap<Integer,Integer> referMap = new HashMap<Integer,Integer>();
						for(Integer datamemberID:cdms){
							HashSet<Integer> set = CustomDataMember
									.getViewHasDataMember(datamemberID);
							for (Integer vid : set) {
								if(vid!=viewID){
									if (!referMap.containsKey(vid)) {
										referMap.put(vid, new Integer(0));
									}
									int count = referMap.get(vid);
									count++;
									referMap.put(vid, count);
								}
							}
						}
						View.storeReference(viewID, referMap) ;
						
						//软件制品解锁
						Collaboration.getInstance().recoverAuthority(Collaboration.VIEW, initialViewID);
						
						result.put("status", this.STATUS_OK);
						result.put("viewID", viewID);
					} else {
						Collaboration.getInstance().recoverAuthority(
								Collaboration.VIEW, viewID);
						result.put("status", this.STATUS_CONFLICT);
					}
				}

			} else {
				//没有编辑权限，返回noauthority
				result.put("status", this.STATUS_NOAUTHORITY);
			}
			
			//最终返回结果
			response.getWriter().print(result);
 		}
 		else if(option.equals("storelayout")){
			String str = URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			String user = (String)regtJSON.get("user") ;
			int viewID = Integer.parseInt(((String)regtJSON.get("viewID")));
 			int layout = Integer.parseInt((String) regtJSON.get("layout"));

			Connection con = DBConnectionFactory.getConnection();
			try {
				PreparedStatement ps = con
						.prepareStatement("insert into user_view(user_id,view_id,layout) values(?,?,?)"
								+ " on duplicate key update layout =values(layout)");
				ps.setInt(1, UserNameIDCache.getInstance().getUserID(user));
				ps.setInt(2, viewID);
				ps.setInt(3, layout);
				ps.executeUpdate();
				ps.close();
				con.close();
			} catch (SQLException e) {
				// TODO: handle exception
				e.printStackTrace();
			}catch (Throwable e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			
 		}
 		else if(option.equals("viewDMInit")){
			String str = URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			int viewID = Integer.parseInt((String)regtJSON.get("vid"));
			String lang = View.getLanguage(viewID);
			JSONArray elements  = new JSONArray();
			ArrayList<DataMember> datamembers = View.getDataMembers(viewID) ;
			try {
				for(DataMember datamember:datamembers){
					JSONObject jsob = new JSONObject();
					int dmtype = 0;
					int dmid = 0;
					String name = null;
					int inverse = 0;
					int arity = 2;
					int functional = 0;
					int value_type = 0;
					
					if(datamember instanceof CustomDataMember){
						dmtype = DataMember.CUSTOM_DATAMEMBER;
						CustomDataMember cdm = (CustomDataMember) datamember;
						dmid  = cdm.getID();
					    name =  View.getLabelInView(viewID, dmtype, dmid);
						arity = cdm.getArity();
						functional = cdm.getFunctional()?1:0;
						value_type =cdm.getValueType();
					}else{
						dmtype = DataMember.URI_DATAMEMBER;
						URIDataMember udm = (URIDataMember) datamember;
						dmid =  udm.getID();
						name =  View.getLabelInView(viewID, dmtype, dmid);
						inverse =udm.isInverse()?1:0;
						functional = udm.getFunctional()?1:0;
						value_type = udm.getValueType() ;
					}
					
					jsob.put("dmtype", dmtype) ;
					jsob.put("dmid", dmid) ;
					jsob.put("name", name);
					jsob.put("inverse", inverse);
					jsob.put("arity", arity) ;
					jsob.put("vtype",value_type );
					jsob.put("functional", functional);
			        elements.add(jsob) ;
				}
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			response.getWriter().print(elements) ;
 		}else if(option.equals("ruleinfo")){
 			String str = URLDecoder.decode(json,"utf-8");
 			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			int dmID = Integer.parseInt((String)regtJSON.get("dmid"));
			String lang = (String)regtJSON.get("lang");
			ArrayList<Rule> rules = new ArrayList<Rule>();
			CustomDataMember cdm = CustomDataMember.getCustomDataMemberById(dmID);
			if(cdm!=null){
				rules = cdm.getRules();
			}
			JSONArray result = new JSONArray();
			for(Rule r:rules){
				ArrayList<Integer> rowIDs = r.getRowIDs();
				JSONObject jsob = new JSONObject();
				JSONArray body = new JSONArray();
				Atom<Term> ruleHead = r.getHead();
				JSONObject head = this.handleAtom(ruleHead, lang);
				jsob.put("head", head);
				ArrayList<Atom<Term>> ruleBody = r.getBody();
				for(Atom<Term> atom:ruleBody){
					JSONObject batomjson = this.handleAtom(atom, lang);
					body.add(batomjson);
				}
				jsob.put("body", body);
				JSONArray rows = new JSONArray();
				for(Integer rowID:rowIDs){
					rows.add(rowID);
				}
				jsob.put("rows", rows);
				jsob.put("isTarget",r.getFlag());
				result.add(jsob);
			}
			
			response.getWriter().print(result) ;
 		}
	}
	
	/**
	 * 返回了一个公式对应元素: arity,isInner,pred title,pred label, term label
	 * 假定这里不存在常量的term
	 * @param atom
	 * @return
	 */
	public JSONObject handleAtom(Atom<Term> atom,String lang){
		JSONObject jsob = new JSONObject();
		Predicate pred = atom.getPredicate();
		int arity = pred.getArity();
		boolean isInner = false;
		String predTitle = null;
		String predLabel = null;
		if(pred.getResource() instanceof URIResource){
			URIResource resource = (URIResource)pred.getResource();
			predTitle = resource.getURI();
			if(resource.isInternalURI()){
				isInner  = true;
				ArrayList<String> infos = URIUtil.parseCustomDatamemberURI(predTitle) ;
				predLabel= infos.get(4) ;
			}else{
				try {
					int id = URIIDCache.getInstance().getURIID(predTitle, false);
					predLabel = URILabelCache.getInstance().getLabel(id, lang);
				} catch (Throwable e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			
				if (predLabel==null || predLabel.trim().equals("")) {
					predLabel = URIUtil.getLocalname(predTitle);
				}
			}
			jsob.put("arity", arity);
			jsob.put("isInner", isInner);
			jsob.put("title", predTitle);
			jsob.put("label", predLabel);
			ArrayList<Term> terms = atom.getTerms();
			JSONArray termArray = new JSONArray();
			for(Term term:terms){
				if(!(term instanceof Variable)){
					throw new IllegalArgumentException("The argument must be variable");
				}else{
					termArray.add(term.toString());
				}
			}
			jsob.put("args",termArray);
			
		}else{
			throw new IllegalArgumentException("The resource must be URIResource");
		}
		return jsob;
	}

}
